package com.web.accumulate.service;

import com.alibaba.fastjson.JSONObject;
import com.web.accumulate.entity.AccumulateTransaction;
import com.web.accumulate.mapper.AccumulateMapper;
import com.web.config.RabbitConfig;
import com.web.contract.controller.ContractController;
import com.web.position.entity.Position;
import com.web.position.service.PositionService;
import com.web.transaction.entity.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AccumulateService {

	private static final Logger logger = LoggerFactory.getLogger(AccumulateService.class);

	@Resource
    private AccumulateMapper accumulateMapper;

	@Autowired
    private PositionService positionService;

	@Autowired
	private RabbitConfig rabbitConfig;

	public int addAccumulateTransaction(AccumulateTransaction at) {
		return accumulateMapper.addAccumulateTransaction(at);
	}

	public List<AccumulateTransaction> getAccumulateTransactions(AccumulateTransaction at) {
		return accumulateMapper.getAccumulateTransactions(at);
	}

	public void accumulateTimedTask() {
		//定时作业使用
		List<String> status = new ArrayList<String>();
		status.add(Position.POSITION_STATUS_NORMAL);
		List<Position> positions = positionService.getPositionsByStatus(status);
		accumulate(positions);

		List<AccumulateTransaction> accumulateTransactions = accumulateMapper.getAccumulateTransactionsByStatus(status);
		if(!accumulateTransactions.isEmpty()){
			for (AccumulateTransaction accumulateTransaction : accumulateTransactions) {
				rabbitConfig.sendAccumulated(accumulateTransaction);
			}
			//修改状态为DON.
			if(accumulateMapper.updateStatus(accumulateTransactions) <= 0){
				logger.warn("更新累总数据失败");
			}
		}else {
			logger.warn("无累总数据");
		}




	}

	public void accumulate(List<Position> list) {
		Map<String,List<Position>> group = list.stream().collect(Collectors.groupingBy(Position::groupKey, Collectors.toList()));
		group.forEach((key,positions) -> {
			BigDecimal buyAmt = positions.stream().filter(Position::isBankBuy).collect(Collectors.reducing(BigDecimal.ZERO,Position::getAmount,(v1,v2) -> v1.add(v2)));
			BigDecimal buyHkdEquAmt = positions.stream().filter(Position::isBankBuy).collect(Collectors.reducing(BigDecimal.ZERO,Position::getHkdEquAmt,(v1,v2) -> v1.add(v2)));

			BigDecimal sellAmt = positions.stream().filter(Position::isBankSell).collect(Collectors.reducing(BigDecimal.ZERO,Position::getAmount,(v1,v2) -> v1.add(v2)));
			BigDecimal sellHkdEquAmt = positions.stream().filter(Position::isBankSell).collect(Collectors.reducing(BigDecimal.ZERO,Position::getHkdEquAmt,(v1,v2) -> v1.add(v2)));

			if(buyAmt.signum() != 0) {
				String accumulateNo = generateAccumulate(key, positions, buyAmt, buyHkdEquAmt);
				positions.forEach(p -> {
					p.setAccumulatedNo(accumulateNo);
					p.setStatus(Position.POSITION_STATUS_COMPLETE);
					positionService.amendPosition(p);
				});
			}
			if(sellAmt.signum() != 0) {
				String accumulateNo = generateAccumulate(key, positions, sellAmt, sellHkdEquAmt);
				positions.forEach(p -> {
					System.out.println(JSONObject.toJSONString(p));
					p.setAccumulatedNo(accumulateNo);
					p.setStatus(Position.POSITION_STATUS_COMPLETE);
					positionService.amendPosition(p);
				});
			}
		});
	}

	private String generateAccumulate(String key,List<Position> positions,BigDecimal amount,BigDecimal hkdEquAmt) {
		String[] keys = key.split("#");
		AccumulateTransaction at = new AccumulateTransaction();
		at.setTradeDate(LocalDate.parse(keys[0], Transaction.yyyyMMdd));
		at.setValueDate(LocalDate.parse(keys[0], Transaction.yyyyMMdd));
		at.setCurrency(keys[1]);
		at.setAmount(amount);
		at.setHkdEquAmt(hkdEquAmt);
		at.setStatus(AccumulateTransaction.ACCUMULATE_STATUS_NORMAL);
		at.setBuySellOption(keys[2]);
		addAccumulateTransaction(at);
		return at.getAccumulatedNo();
	}
}
